using System;
using System.Collections.Generic;
using System.Text;
using Csla;
using System.Data;
using Active.Core.DB;
using Csla.Data;
using DesignByContract;

namespace Active.Core
{
    /// <summary>
    /// The read only advance info list.
    /// </summary>
    [Serializable()]
    public class AdvanceList :
      ReadOnlyListBase<AdvanceList, AdvanceInfo>
    {
        #region Paging

        private int _totalRecordsCount;
        /// <summary>
        /// Gets the total records count.
        /// </summary>
        /// <value>The total records count.</value>
        public int TotalRecordsCount
        {
            get
            {
                return _totalRecordsCount;
            }
        }

        private int _pageNo;
        /// <summary>
        /// Gets the page no.
        /// </summary>
        /// <value>The page no.</value>
        public int PageNo
        {
            get
            {
                return _pageNo;
            }
        }

        private int _pageSize;
        /// <summary>
        /// Gets the size of the page.
        /// </summary>
        /// <value>The size of the page.</value>
        public int PageSize
        {
            get
            {
                return _pageSize;
            }
        }

        private bool _allowPaging = false;
        /// <summary>
        /// Gets a value indicating whether [allow paging].
        /// </summary>
        /// <value><c>true</c> if [allow paging]; otherwise, <c>false</c>.</value>
        public bool AllowPaging
        {
            get
            {
                return _allowPaging;
            }
        }

        #endregion

        #region Authorization Rules

        public static bool CanGetObject()
        {
            // TODO: customize to check user role
            //return ApplicationContext.User.IsInRole("");
            return true;
        }

        #endregion

        #region Factory Methods

        public static AdvanceList GetAdvanceList(int ownerId)
        {
            return DataPortal.Fetch<AdvanceList>(new Criteria(ownerId));
        }

        /// <summary>
        /// Gets the advance list.
        /// </summary>
        /// <param name="ownerId">The owner id.</param>
        /// <param name="pageNo">The page no.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <returns></returns>
        public static AdvanceList GetAdvanceList(int ownerId, int pageNo, int pageSize)
        {
            Check.Require(pageNo > 0);
            Check.Require(pageSize > 0);
            return DataPortal.Fetch<AdvanceList>(new Criteria(ownerId, pageNo, pageSize));
        }

        private AdvanceList()
        { /* require use of factory methods */ }

        #endregion

        #region Data Access

        [Serializable()]
        private class Criteria
        {
            private int _pageNo;
            public int PageNo
            {
                get
                {
                    return _pageNo;
                }
            }

            private int _pageSize;
            public int PageSize
            {
                get
                {
                    return _pageSize;
                }
            }

            private bool _allowPaging = false;
            public bool AllowPaging
            {
                get
                {
                    return _allowPaging;
                }
            }

            private int _ownerId = 0;
            public int OwnerId
            {
                get
                {
                    return _ownerId;
                }
            }

            public Criteria(int ownerId)
            {
                _ownerId = ownerId;
            }

            public Criteria(int ownerId, int pageNo, int pageSize)
            {
                _ownerId = ownerId;
                _pageNo = pageNo;
                _pageSize = pageSize;
                if (_pageNo > 0 && _pageSize > 0)
                {
                    _allowPaging = true;
                }
            }
        }

        private void DataPortal_Fetch(Criteria criteria)
        {
            RaiseListChangedEvents = false;
            IsReadOnly = false;

            NBearLite.SelectSqlSection select =
                DataService.DBService.Select(Tables.Advances);

            if (criteria.AllowPaging)
            {
                select.SetSelectRange(criteria.PageSize,
                    (criteria.PageNo - 1) * criteria.PageSize,
                    Tables.Advances.Id);
                _allowPaging = true;
                _pageNo = criteria.PageNo;
                _pageSize = criteria.PageSize;
            }
            if (criteria.OwnerId > 0)
            {
                select.Where(Tables.Advances.OwnerId == criteria.OwnerId);
            }
            select.OrderBy(Tables.Advances.Id.Desc);
            using (SafeDataReader dr = new SafeDataReader(select.ToDataReader()))
            {
                while (dr.Read())
                    Add(AdvanceInfo.GetAdvanceInfo(dr));
            }
            if (_allowPaging)
            {
                select = DataService.DBService.Select(Tables.Advances,
                    Tables.Advances.Id.Count());
                if (criteria.OwnerId > 0)
                {
                    select.Where(Tables.Advances.OwnerId == criteria.OwnerId);
                }
                _totalRecordsCount = (int)select.ToScalar();
            }
            else
            {
                _totalRecordsCount = this.Count;
            }
            IsReadOnly = true;
            RaiseListChangedEvents = true;
        }

        #endregion
    }
}

